
The Carolina Parakeet was once common in the United States -- it ranged from the swamps of Florida to the Ohio River Valley. As early as the 1700s, naturalists began noticing a decline in the parakeet's numbers. Its population dropped precipitously in the 1800s, and by the early 1900s, it was functionally gone from the wild. The last wild Carolina Parakeet was spotted in 1915; the species was declared extinct in 1939.
With user-generated data from the Cornell Bird Lab, we can take a look at some of the last recorded sightings of the Carolina Parakeet in the US.
Thanks to programs like the R. Dale Twining project, nature journals, personal diaries, and birding lists of long-deceased ornithologists and even amateur birders have been preserved digitally. While the eBird API is more commonly used to display recent birding observations, we searched the oldest dates in eBird for sightings of the Carolina Parakeet--elusive even in the 1800s!
This project not only provided a snapshot in time as one of America's most stunning birds was fading from existence; it also connected our team to the personal histories of birdwatchers from long ago.
import pandas as pd
from config import mapbox_token
import plotly.express as px
import plotly.graph_objs as go
import os
import numpy as np
from datetime import datetime
import calendar
%reload_ext lab_black
px.set_mapbox_access_token(mapbox_token)
# Resource paths
DATES_WITH_DATA = os.path.join("resources", "dates_with_data_1800-1999.csv")
CAROLINA_PARAKEETS = os.path.join("resources", "carolina_parakeets.csv")
FLORIDA_PARAKEETS = os.path.join("resources", "florida_parakeets.csv")
AUSTIN_PARAKEETS = os.path.join("resources", "austin_parakeets.csv")
First we scraped the API to find which dates had contributors in the database. It's important to note that eBird tracks observations of birds, not actual bird populations.
We found that from 1800-1999, there were nearly 35,000 days with data!
# Read in data on numbers of observations & contributors per day from 1800-1999
date_headers_separated = ["year", "month", "day"]
dates_df = pd.read_csv(DATES_WITH_DATA)
dates_df["Date"] = pd.to_datetime(dates_df[date_headers_separated])
dates_df = dates_df.drop(date_headers_separated, axis=1)
move_col = dates_df.pop("Date")
dates_df.insert(0, "Date", move_col)
dates_df
The database entries came primarily from observations after 1950, but there were many dates with data even far earlier than that!
fig = px.scatter(
dates_df,
x="Date",
y="contributors",
color_discrete_sequence=["slategray"],
title="Number of Historic Contributors to eBird Database per Day (1800-1999)",
width=1000,
height=600,
)
fig.show()
fig = px.scatter(
dates_df,
x="Date",
y="contributors",
color_discrete_sequence=["slategray"],
range_x=[pd.to_datetime(["1950-01-01"])[0], pd.to_datetime(["2000-01-01"])[0]],
title="Number of Historic Contributors to eBird Database per Day (1950-1999)",
width=1000,
height=600,
)
fig.show()
Most observations are made in the summer months...
since_1980_df = dates_df.loc[dates_df["Date"] > pd.to_datetime(["1980-01-01"])[0]]
months = []
for month in np.arange(1, 13):
months.append(calendar.month_name[month])
fig = px.box(
since_1980_df,
x=pd.DatetimeIndex(since_1980_df["Date"]).month,
y="contributors",
points="all",
color_discrete_sequence=["slategray"],
title="Monthly Historic Contributors to eBird Database (1980-1999)",
width=1000,
height=600,
)
fig.update_layout(
xaxis=dict(tickmode="array", tickvals=np.arange(1, 13), ticktext=months)
)
fig.show()
...and on the weekends.
since_1980_df = dates_df.loc[dates_df["Date"] > pd.to_datetime(["1980-01-01"])[0]]
weekdays = [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
]
fig = px.box(
since_1980_df,
x=pd.DatetimeIndex(since_1980_df["Date"]).weekday,
y="contributors",
points="all",
color_discrete_sequence=["slategray"],
title="Weekday Historic Contributors to eBird Database (1980-1999)",
width=1000,
height=600,
)
fig.update_layout(
xaxis=dict(tickmode="array", tickvals=np.arange(0, 7), ticktext=weekdays)
)
fig.show()
Before the Carolina Parakeet went extinct, the eBird dataset records 18 reported sightings, ranging from the year 1810-1881.
columns_dict = {
"comName": "Species",
"sciName": "Scientific Name",
"locName": "Location",
"obsDt": "Date",
"howMany": "Number Seen",
"lat": "Latitude",
"lng": "Longitude",
}
carolina_df = (
pd.read_csv(CAROLINA_PARAKEETS)
.drop(
["speciesCode", "locId", "obsValid", "obsReviewed", "locationPrivate", "subId"],
axis=1,
)
.rename(columns=columns_dict)
)
carolina_df["Number Seen"] = carolina_df["Number Seen"].fillna(1)
carolina_df["Decade"] = pd.DatetimeIndex(carolina_df["Date"]).year // 10 * 10
carolina_df
These last few observations of the dying species were spread throughout the Ohio River Valley and the southeastern United States, consistent with what scientists know of the parakeet's full range in the centuries before its extinction.
# Map historic observations of the now-extinct Carolina Parakeet
fig = px.scatter_mapbox(
carolina_df,
lat="Latitude",
lon="Longitude",
hover_name="Location",
hover_data={"Date": "|%B %d, %Y", "Latitude": False, "Longitude": False},
color_discrete_sequence=["red"],
mapbox_style="stamen-watercolor",
width=1000,
height=600,
zoom=4,
)
fig.show()
In each decade of the 19th century, eBird lists no more than five observations.
fig = px.histogram(
x=carolina_df["Decade"],
color_discrete_sequence=["red"],
nbins=10,
width=800,
height=600,
)
fig.show()
In the 1960s, pet stores in the United States began importing the Monk Parakeet; however, several shipments of the birds got loose. Over the course of the 60s and 70s, bird owners who released their pets into the wild and lost shipments of Monk Parakeets allowed small populations of the bird to become established, primarily in Florida.
We searched eBird for the first recorded sightings of the Monk Parakeet, and we found some of the earlierst observations beginning in 1975!
# Read in saved data on Monk Parakeets' arrival & population growth in Florida
florida_df = (
pd.read_csv(FLORIDA_PARAKEETS)
.drop(
["speciesCode", "locId", "obsValid", "obsReviewed", "locationPrivate", "subId"],
axis=1,
)
.rename(columns=columns_dict)
)
florida_df["Decade"] = pd.DatetimeIndex(florida_df["Date"]).year // 10 * 10
florida_df["Number Seen"] = florida_df["Number Seen"].fillna(1)
florida_df
This animation shows how the population of Monk Parakeets in Florida became established, grew through the end of the 20th century, and exploded in the early 2000s. While the population size has leveled off in recent years, ecologists still consider the Monk Parakeet to be an invasive species.
# Animated map of observations of the Monk Parakeet's introduction to and subsequent population growth in Florida
fig = px.scatter_mapbox(
florida_df,
lat="Latitude",
lon="Longitude",
animation_frame=pd.DatetimeIndex(florida_df["Date"]).year // 5 * 5,
hover_name="Location",
hover_data={
"Date": "|%B %d, %Y",
"Number Seen": True,
"Latitude": False,
"Longitude": False,
},
color_discrete_sequence=["green"],
mapbox_style="stamen-watercolor",
width=1000,
height=600,
zoom=5,
)
fig.show()
fig = px.histogram(
x=pd.DatetimeIndex(florida_df["Date"]).year,
color_discrete_sequence=["green"],
width=1000,
height=600,
)
fig.show()
The Monk Parakeet, scientists believe, have taken over the niche that the Carolina Parakeet once filled. The chart below plots observations of both species on a logarithmic scale.
old_new_df = pd.merge(carolina_df, florida_df, how="outer")
fig = px.histogram(
old_new_df,
x=pd.DatetimeIndex(old_new_df["Date"]).year,
log_y=True,
color="Species",
color_discrete_sequence=["red", "green"],
width=1000,
height=600,
)
fig.show()
Monk Parakeets have spread across the southern United States, and Austin, TX is home to one of the largest populations outside of Florida.
Using the eBird data, we were able to find some of the first sightings of the Monk Parakeet in Austin after they became established here in the 1970s.
austin_df = (
pd.read_csv(AUSTIN_PARAKEETS)
.drop(
["speciesCode", "locId", "obsValid", "obsReviewed", "locationPrivate", "subId"],
axis=1,
)
.rename(columns=columns_dict)
)
austin_df["Decade"] = pd.DatetimeIndex(austin_df["Date"]).year // 10 * 10
austin_df["Number Seen"] = austin_df["Number Seen"].fillna(1)
austin_df
In this animation, you can see where people have spotted the Monk Parakeet in Austin over the years.
# create the plot
fig = px.scatter_mapbox(
austin_df,
lat="Latitude",
lon="Longitude",
animation_frame=pd.DatetimeIndex(austin_df["Date"]).year // 2 * 2,
hover_name="Location",
hover_data={
"Date": "|%B %d, %Y",
"Latitude": False,
"Longitude": False,
"Number Seen": True,
},
color_discrete_sequence=["blue"],
mapbox_style="outdoors",
width=1000,
height=600,
zoom=10,
)
fig.show()
fig = px.histogram(
x=pd.DatetimeIndex(austin_df["Date"]).year,
color_discrete_sequence=["blue"],
width=1000,
height=600,
log_y=True,
)
fig.show()
If you want to spot a parakeet in Austin, you'll want to spend some time along the river or in one of the city's green spaces like the UT intramural fields, the Mueller Park district, or the Pease District Park!
fig = px.density_mapbox(
austin_df,
lat="Latitude",
lon="Longitude",
mapbox_style="stamen-terrain",
z="Number Seen",
radius=20,
opacity=0.8,
hover_data={
"Latitude": False,
"Longitude": False,
"Location": True,
"Number Seen": True,
},
zoom=10,
width=1000,
height=600,
)
fig.show()